/*
 * 文 件 名:  UserRealm.java
 * 版    权:  Fanying Information Technologies Co., Ltd. Copyright 2013-2023,  All rights reserved
 * 描    述:  <描述>
 * 修 改 人:  fhxin
 * 修改时间:  2017-5-9
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.isoftstone.platform.shiro;

import com.isoftstone.platform.common.constant.PlatformConstant;
import com.isoftstone.platform.model.entity.PtMenuEntity;
import com.isoftstone.platform.model.entity.PtUserEntity;
import com.isoftstone.platform.sm.service.UserInfoService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import javax.annotation.Resource;
import java.util.List;

/**
 * <一句话功能简述>
 * <功能详细描述>
 * 
 * @author  fhxin
 * @version  [STUDY V100R002C01, 2017-5-9]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class UserRealm extends AuthorizingRealm
{
    @Resource
    private UserInfoService userInfoService;
    
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
    {
        
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        
        Session session = SecurityUtils.getSubject().getSession();
        
        List<PtMenuEntity> list = (List<PtMenuEntity>)session.getAttribute("sysMenuList");
        if (list == null)
        {
            String siteLanguage = (String)session.getAttribute("siteLanguage");
            PtUserEntity userEntity = (PtUserEntity)session.getAttribute("userInfo");
            list = userInfoService.selectMenu(siteLanguage, userEntity.getUserUuid());
        }
        String privilege;
        info.addStringPermission("gdmt_data_MENU_103");
        info.addStringPermission("gdmt_data_MENU_102");
        info.addStringPermission("gdmt_data_MENU_101");
        info.addStringPermission("gdmt_class_info");

        for (PtMenuEntity sysMenuEntity : list)
        {
            privilege = sysMenuEntity.getPrivilegeCode();
            if (privilege != null && !"".equals(privilege))
            {
                info.addStringPermission(privilege);
            }
        }
        return info;
    }
    
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authentoken)
        throws AuthenticationException
    {
        
        CaptchaUsernamePasswordToken token = (CaptchaUsernamePasswordToken)authentoken;
        String captcha = token.getCaptcha();
        String userName = token.getUsername();
        String password = new String(token.getPassword());
        
        PtUserEntity userEntity = userInfoService.autoUserInfo(userName, password);
        Session session = SecurityUtils.getSubject().getSession();
        
        String genCaptcha = (String)session.getAttribute(PlatformConstant.CAPTCHA_CODE_KEY);
        
        if (userEntity == null)
        {
            throw new AuthenticationException("user is auth fail!");
        }
        else if (captcha == null || (!captcha.equalsIgnoreCase(genCaptcha)))
        {
            String isAuthCode = (String)session.getAttribute("isAuthCode");
            if (isAuthCode != null && !"false".equals(isAuthCode))
            {
                throw new AuthenticationException("verification code must be filled!");
            }
            
        }
        
        session.setAttribute("userInfo", userEntity);
        
        ByteSource salt = ByteSource.Util.bytes(org.apache.shiro.util.ByteSource.Util.bytes(userName));
        AuthenticationInfo info = new SimpleAuthenticationInfo(userEntity, password, salt, getName());
        
        return info;
    }
}